1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gtk.FlowBox; 26 27 private import gio.ListModelIF; 28 private import glib.ConstructionException; 29 private import glib.ListG; 30 private import gobject.ObjectG; 31 private import gobject.Signals; 32 private import gtk.Adjustment; 33 private import gtk.FlowBoxChild; 34 private import gtk.OrientableIF; 35 private import gtk.OrientableT; 36 private import gtk.Widget; 37 private import gtk.c.functions; 38 public import gtk.c.types; 39 private import std.algorithm; 40 41 42 /** 43 * A `GtkFlowBox` puts child widgets in reflowing grid. 44 * 45 * For instance, with the horizontal orientation, the widgets will be 46 * arranged from left to right, starting a new row under the previous 47 * row when necessary. Reducing the width in this case will require more 48 * rows, so a larger height will be requested. 49 * 50 * Likewise, with the vertical orientation, the widgets will be arranged 51 * from top to bottom, starting a new column to the right when necessary. 52 * Reducing the height will require more columns, so a larger width will 53 * be requested. 54 * 55 * The size request of a `GtkFlowBox` alone may not be what you expect; 56 * if you need to be able to shrink it along both axes and dynamically 57 * reflow its children, you may have to wrap it in a `GtkScrolledWindow` 58 * to enable that. 59 * 60 * The children of a `GtkFlowBox` can be dynamically sorted and filtered. 61 * 62 * Although a `GtkFlowBox` must have only `GtkFlowBoxChild` children, you 63 * can add any kind of widget to it via [method@Gtk.FlowBox.insert], and a 64 * `GtkFlowBoxChild` widget will automatically be inserted between the box 65 * and the widget. 66 * 67 * Also see [class@Gtk.ListBox]. 68 * 69 * # CSS nodes 70 * 71 * ``` 72 * flowbox 73 * ├── flowboxchild 74 * │ ╰── <child> 75 * ├── flowboxchild 76 * │ ╰── <child> 77 * ┊ 78 * ╰── [rubberband] 79 * ``` 80 * 81 * `GtkFlowBox` uses a single CSS node with name flowbox. `GtkFlowBoxChild` 82 * uses a single CSS node with name flowboxchild. For rubberband selection, 83 * a subnode with name rubberband is used. 84 * 85 * # Accessibility 86 * 87 * `GtkFlowBox` uses the %GTK_ACCESSIBLE_ROLE_GRID role, and `GtkFlowBoxChild` 88 * uses the %GTK_ACCESSIBLE_ROLE_GRID_CELL role. 89 */ 90 public class FlowBox : Widget, OrientableIF 91 { 92 /** the main Gtk struct */ 93 protected GtkFlowBox* gtkFlowBox; 94 95 /** Get the main Gtk struct */ 96 public GtkFlowBox* getFlowBoxStruct(bool transferOwnership = false) 97 { 98 if (transferOwnership) 99 ownedRef = false; 100 return gtkFlowBox; 101 } 102 103 /** the main Gtk struct as a void* */ 104 protected override void* getStruct() 105 { 106 return cast(void*)gtkFlowBox; 107 } 108 109 /** 110 * Sets our main struct and passes it to the parent class. 111 */ 112 public this (GtkFlowBox* gtkFlowBox, bool ownedRef = false) 113 { 114 this.gtkFlowBox = gtkFlowBox; 115 super(cast(GtkWidget*)gtkFlowBox, ownedRef); 116 } 117 118 // add the Orientable capabilities 119 mixin OrientableT!(GtkFlowBox); 120 121 122 /** */ 123 public static GType getType() 124 { 125 return gtk_flow_box_get_type(); 126 } 127 128 /** 129 * Creates a `GtkFlowBox`. 130 * 131 * Returns: a new `GtkFlowBox` 132 * 133 * Throws: ConstructionException GTK+ fails to create the object. 134 */ 135 public this() 136 { 137 auto __p = gtk_flow_box_new(); 138 139 if(__p is null) 140 { 141 throw new ConstructionException("null returned by new"); 142 } 143 144 this(cast(GtkFlowBox*) __p); 145 } 146 147 /** 148 * Adds @child to the end of @self. 149 * 150 * If a sort function is set, the widget will 151 * actually be inserted at the calculated position. 152 * 153 * See also: [method@Gtk.FlowBox.insert]. 154 * 155 * Params: 156 * child = the `GtkWidget` to add 157 * 158 * Since: 4.6 159 */ 160 public void append(Widget child) 161 { 162 gtk_flow_box_append(gtkFlowBox, (child is null) ? null : child.getWidgetStruct()); 163 } 164 165 /** 166 * Binds @model to @box. 167 * 168 * If @box was already bound to a model, that previous binding is 169 * destroyed. 170 * 171 * The contents of @box are cleared and then filled with widgets that 172 * represent items from @model. @box is updated whenever @model changes. 173 * If @model is %NULL, @box is left empty. 174 * 175 * It is undefined to add or remove widgets directly (for example, with 176 * [method@Gtk.FlowBox.insert]) while @box is bound to a model. 177 * 178 * Note that using a model is incompatible with the filtering and sorting 179 * functionality in `GtkFlowBox`. When using a model, filtering and sorting 180 * should be implemented by the model. 181 * 182 * Params: 183 * model = the `GListModel` to be bound to @box 184 * createWidgetFunc = a function that creates widgets for items 185 * userData = user data passed to @create_widget_func 186 * userDataFreeFunc = function for freeing @user_data 187 */ 188 public void bindModel(ListModelIF model, GtkFlowBoxCreateWidgetFunc createWidgetFunc, void* userData, GDestroyNotify userDataFreeFunc) 189 { 190 gtk_flow_box_bind_model(gtkFlowBox, (model is null) ? null : model.getListModelStruct(), createWidgetFunc, userData, userDataFreeFunc); 191 } 192 193 /** 194 * Returns whether children activate on single clicks. 195 * 196 * Returns: %TRUE if children are activated on single click, 197 * %FALSE otherwise 198 */ 199 public bool getActivateOnSingleClick() 200 { 201 return gtk_flow_box_get_activate_on_single_click(gtkFlowBox) != 0; 202 } 203 204 /** 205 * Gets the nth child in the @box. 206 * 207 * Params: 208 * idx = the position of the child 209 * 210 * Returns: the child widget, which will 211 * always be a `GtkFlowBoxChild` or %NULL in case no child widget 212 * with the given index exists. 213 */ 214 public FlowBoxChild getChildAtIndex(int idx) 215 { 216 auto __p = gtk_flow_box_get_child_at_index(gtkFlowBox, idx); 217 218 if(__p is null) 219 { 220 return null; 221 } 222 223 return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) __p); 224 } 225 226 /** 227 * Gets the child in the (@x, @y) position. 228 * 229 * Both @x and @y are assumed to be relative to the origin of @box. 230 * 231 * Params: 232 * x = the x coordinate of the child 233 * y = the y coordinate of the child 234 * 235 * Returns: the child widget, which will 236 * always be a `GtkFlowBoxChild` or %NULL in case no child widget 237 * exists for the given x and y coordinates. 238 */ 239 public FlowBoxChild getChildAtPos(int x, int y) 240 { 241 auto __p = gtk_flow_box_get_child_at_pos(gtkFlowBox, x, y); 242 243 if(__p is null) 244 { 245 return null; 246 } 247 248 return ObjectG.getDObject!(FlowBoxChild)(cast(GtkFlowBoxChild*) __p); 249 } 250 251 /** 252 * Gets the horizontal spacing. 253 * 254 * Returns: the horizontal spacing 255 */ 256 public uint getColumnSpacing() 257 { 258 return gtk_flow_box_get_column_spacing(gtkFlowBox); 259 } 260 261 /** 262 * Returns whether the box is homogeneous. 263 * 264 * Returns: %TRUE if the box is homogeneous. 265 */ 266 public bool getHomogeneous() 267 { 268 return gtk_flow_box_get_homogeneous(gtkFlowBox) != 0; 269 } 270 271 /** 272 * Gets the maximum number of children per line. 273 * 274 * Returns: the maximum number of children per line 275 */ 276 public uint getMaxChildrenPerLine() 277 { 278 return gtk_flow_box_get_max_children_per_line(gtkFlowBox); 279 } 280 281 /** 282 * Gets the minimum number of children per line. 283 * 284 * Returns: the minimum number of children per line 285 */ 286 public uint getMinChildrenPerLine() 287 { 288 return gtk_flow_box_get_min_children_per_line(gtkFlowBox); 289 } 290 291 /** 292 * Gets the vertical spacing. 293 * 294 * Returns: the vertical spacing 295 */ 296 public uint getRowSpacing() 297 { 298 return gtk_flow_box_get_row_spacing(gtkFlowBox); 299 } 300 301 /** 302 * Creates a list of all selected children. 303 * 304 * Returns: A `GList` containing the `GtkWidget` for each selected child. 305 * Free with g_list_free() when done. 306 */ 307 public ListG getSelectedChildren() 308 { 309 auto __p = gtk_flow_box_get_selected_children(gtkFlowBox); 310 311 if(__p is null) 312 { 313 return null; 314 } 315 316 return new ListG(cast(GList*) __p); 317 } 318 319 /** 320 * Gets the selection mode of @box. 321 * 322 * Returns: the `GtkSelectionMode` 323 */ 324 public GtkSelectionMode getSelectionMode() 325 { 326 return gtk_flow_box_get_selection_mode(gtkFlowBox); 327 } 328 329 /** 330 * Inserts the @widget into @box at @position. 331 * 332 * If a sort function is set, the widget will actually be inserted 333 * at the calculated position. 334 * 335 * If @position is -1, or larger than the total number of children 336 * in the @box, then the @widget will be appended to the end. 337 * 338 * Params: 339 * widget = the `GtkWidget` to add 340 * position = the position to insert @child in 341 */ 342 public void insert(Widget widget, int position) 343 { 344 gtk_flow_box_insert(gtkFlowBox, (widget is null) ? null : widget.getWidgetStruct(), position); 345 } 346 347 /** 348 * Updates the filtering for all children. 349 * 350 * Call this function when the result of the filter 351 * function on the @box is changed due ot an external 352 * factor. For instance, this would be used if the 353 * filter function just looked for a specific search 354 * term, and the entry with the string has changed. 355 */ 356 public void invalidateFilter() 357 { 358 gtk_flow_box_invalidate_filter(gtkFlowBox); 359 } 360 361 /** 362 * Updates the sorting for all children. 363 * 364 * Call this when the result of the sort function on 365 * @box is changed due to an external factor. 366 */ 367 public void invalidateSort() 368 { 369 gtk_flow_box_invalidate_sort(gtkFlowBox); 370 } 371 372 /** 373 * Adds @child to the start of @self. 374 * 375 * If a sort function is set, the widget will 376 * actually be inserted at the calculated position. 377 * 378 * See also: [method@Gtk.FlowBox.insert]. 379 * 380 * Params: 381 * child = the `GtkWidget` to add 382 * 383 * Since: 4.6 384 */ 385 public void prepend(Widget child) 386 { 387 gtk_flow_box_prepend(gtkFlowBox, (child is null) ? null : child.getWidgetStruct()); 388 } 389 390 /** 391 * Removes a child from @box. 392 * 393 * Params: 394 * widget = the child widget to remove 395 */ 396 public void remove(Widget widget) 397 { 398 gtk_flow_box_remove(gtkFlowBox, (widget is null) ? null : widget.getWidgetStruct()); 399 } 400 401 /** 402 * Select all children of @box, if the selection 403 * mode allows it. 404 */ 405 public void selectAll() 406 { 407 gtk_flow_box_select_all(gtkFlowBox); 408 } 409 410 /** 411 * Selects a single child of @box, if the selection 412 * mode allows it. 413 * 414 * Params: 415 * child = a child of @box 416 */ 417 public void selectChild(FlowBoxChild child) 418 { 419 gtk_flow_box_select_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct()); 420 } 421 422 /** 423 * Calls a function for each selected child. 424 * 425 * Note that the selection cannot be modified from within 426 * this function. 427 * 428 * Params: 429 * func = the function to call for each selected child 430 * data = user data to pass to the function 431 */ 432 public void selectedForeach(GtkFlowBoxForeachFunc func, void* data) 433 { 434 gtk_flow_box_selected_foreach(gtkFlowBox, func, data); 435 } 436 437 /** 438 * If @single is %TRUE, children will be activated when you click 439 * on them, otherwise you need to double-click. 440 * 441 * Params: 442 * single = %TRUE to emit child-activated on a single click 443 */ 444 public void setActivateOnSingleClick(bool single) 445 { 446 gtk_flow_box_set_activate_on_single_click(gtkFlowBox, single); 447 } 448 449 /** 450 * Sets the horizontal space to add between children. 451 * 452 * Params: 453 * spacing = the spacing to use 454 */ 455 public void setColumnSpacing(uint spacing) 456 { 457 gtk_flow_box_set_column_spacing(gtkFlowBox, spacing); 458 } 459 460 /** 461 * By setting a filter function on the @box one can decide dynamically 462 * which of the children to show. 463 * 464 * For instance, to implement a search function that only shows the 465 * children matching the search terms. 466 * 467 * The @filter_func will be called for each child after the call, and 468 * it will continue to be called each time a child changes (via 469 * [method@Gtk.FlowBoxChild.changed]) or when 470 * [method@Gtk.FlowBox.invalidate_filter] is called. 471 * 472 * Note that using a filter function is incompatible with using a model 473 * (see [method@Gtk.FlowBox.bind_model]). 474 * 475 * Params: 476 * filterFunc = callback that 477 * lets you filter which children to show 478 * userData = user data passed to @filter_func 479 * destroy = destroy notifier for @user_data 480 */ 481 public void setFilterFunc(GtkFlowBoxFilterFunc filterFunc, void* userData, GDestroyNotify destroy) 482 { 483 gtk_flow_box_set_filter_func(gtkFlowBox, filterFunc, userData, destroy); 484 } 485 486 /** 487 * Hooks up an adjustment to focus handling in @box. 488 * 489 * The adjustment is also used for autoscrolling during 490 * rubberband selection. See [method@Gtk.ScrolledWindow.get_hadjustment] 491 * for a typical way of obtaining the adjustment, and 492 * [method@Gtk.FlowBox.set_vadjustment] for setting the vertical 493 * adjustment. 494 * 495 * The adjustments have to be in pixel units and in the same 496 * coordinate system as the allocation for immediate children 497 * of the box. 498 * 499 * Params: 500 * adjustment = an adjustment which should be adjusted 501 * when the focus is moved among the descendents of @container 502 */ 503 public void setHadjustment(Adjustment adjustment) 504 { 505 gtk_flow_box_set_hadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct()); 506 } 507 508 /** 509 * Sets whether or not all children of @box are given 510 * equal space in the box. 511 * 512 * Params: 513 * homogeneous = %TRUE to create equal allotments, 514 * %FALSE for variable allotments 515 */ 516 public void setHomogeneous(bool homogeneous) 517 { 518 gtk_flow_box_set_homogeneous(gtkFlowBox, homogeneous); 519 } 520 521 /** 522 * Sets the maximum number of children to request and 523 * allocate space for in @box’s orientation. 524 * 525 * Setting the maximum number of children per line 526 * limits the overall natural size request to be no more 527 * than @n_children children long in the given orientation. 528 * 529 * Params: 530 * nChildren = the maximum number of children per line 531 */ 532 public void setMaxChildrenPerLine(uint nChildren) 533 { 534 gtk_flow_box_set_max_children_per_line(gtkFlowBox, nChildren); 535 } 536 537 /** 538 * Sets the minimum number of children to line up 539 * in @box’s orientation before flowing. 540 * 541 * Params: 542 * nChildren = the minimum number of children per line 543 */ 544 public void setMinChildrenPerLine(uint nChildren) 545 { 546 gtk_flow_box_set_min_children_per_line(gtkFlowBox, nChildren); 547 } 548 549 /** 550 * Sets the vertical space to add between children. 551 * 552 * Params: 553 * spacing = the spacing to use 554 */ 555 public void setRowSpacing(uint spacing) 556 { 557 gtk_flow_box_set_row_spacing(gtkFlowBox, spacing); 558 } 559 560 /** 561 * Sets how selection works in @box. 562 * 563 * Params: 564 * mode = the new selection mode 565 */ 566 public void setSelectionMode(GtkSelectionMode mode) 567 { 568 gtk_flow_box_set_selection_mode(gtkFlowBox, mode); 569 } 570 571 /** 572 * By setting a sort function on the @box, one can dynamically 573 * reorder the children of the box, based on the contents of 574 * the children. 575 * 576 * The @sort_func will be called for each child after the call, 577 * and will continue to be called each time a child changes (via 578 * [method@Gtk.FlowBoxChild.changed]) and when 579 * [method@Gtk.FlowBox.invalidate_sort] is called. 580 * 581 * Note that using a sort function is incompatible with using a model 582 * (see [method@Gtk.FlowBox.bind_model]). 583 * 584 * Params: 585 * sortFunc = the sort function 586 * userData = user data passed to @sort_func 587 * destroy = destroy notifier for @user_data 588 */ 589 public void setSortFunc(GtkFlowBoxSortFunc sortFunc, void* userData, GDestroyNotify destroy) 590 { 591 gtk_flow_box_set_sort_func(gtkFlowBox, sortFunc, userData, destroy); 592 } 593 594 /** 595 * Hooks up an adjustment to focus handling in @box. 596 * 597 * The adjustment is also used for autoscrolling during 598 * rubberband selection. See [method@Gtk.ScrolledWindow.get_vadjustment] 599 * for a typical way of obtaining the adjustment, and 600 * [method@Gtk.FlowBox.set_hadjustment] for setting the horizontal 601 * adjustment. 602 * 603 * The adjustments have to be in pixel units and in the same 604 * coordinate system as the allocation for immediate children 605 * of the box. 606 * 607 * Params: 608 * adjustment = an adjustment which should be adjusted 609 * when the focus is moved among the descendents of @container 610 */ 611 public void setVadjustment(Adjustment adjustment) 612 { 613 gtk_flow_box_set_vadjustment(gtkFlowBox, (adjustment is null) ? null : adjustment.getAdjustmentStruct()); 614 } 615 616 /** 617 * Unselect all children of @box, if the selection 618 * mode allows it. 619 */ 620 public void unselectAll() 621 { 622 gtk_flow_box_unselect_all(gtkFlowBox); 623 } 624 625 /** 626 * Unselects a single child of @box, if the selection 627 * mode allows it. 628 * 629 * Params: 630 * child = a child of @box 631 */ 632 public void unselectChild(FlowBoxChild child) 633 { 634 gtk_flow_box_unselect_child(gtkFlowBox, (child is null) ? null : child.getFlowBoxChildStruct()); 635 } 636 637 /** 638 * Emitted when the user activates the @box. 639 * 640 * This is a [keybinding signal](class.SignalAction.html). 641 */ 642 gulong addOnActivateCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 643 { 644 return Signals.connect(this, "activate-cursor-child", dlg, connectFlags ^ ConnectFlags.SWAPPED); 645 } 646 647 /** 648 * Emitted when a child has been activated by the user. 649 * 650 * Params: 651 * child = the child that is activated 652 */ 653 gulong addOnChildActivated(void delegate(FlowBoxChild, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 654 { 655 return Signals.connect(this, "child-activated", dlg, connectFlags ^ ConnectFlags.SWAPPED); 656 } 657 658 /** 659 * Emitted when the user initiates a cursor movement. 660 * 661 * This is a [keybinding signal](class.SignalAction.html). 662 * Applications should not connect to it, but may emit it with 663 * g_signal_emit_by_name() if they need to control the cursor 664 * programmatically. 665 * 666 * The default bindings for this signal come in two variants, 667 * the variant with the Shift modifier extends the selection, 668 * the variant without the Shift modifier does not. 669 * There are too many key combinations to list them all here. 670 * 671 * - <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd> 672 * move by individual children 673 * - <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box 674 * - <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages 675 * 676 * Params: 677 * step = the granularity fo the move, as a `GtkMovementStep` 678 * count = the number of @step units to move 679 * extend = whether to extend the selection 680 * modify = whether to modify the selection 681 * 682 * Returns: %TRUE to stop other handlers from being invoked for the event. 683 * %FALSE to propagate the event further. 684 */ 685 gulong addOnMoveCursor(bool delegate(GtkMovementStep, int, bool, bool, FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 686 { 687 return Signals.connect(this, "move-cursor", dlg, connectFlags ^ ConnectFlags.SWAPPED); 688 } 689 690 /** 691 * Emitted to select all children of the box, 692 * if the selection mode permits it. 693 * 694 * This is a [keybinding signal](class.SignalAction.html). 695 * 696 * The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>. 697 */ 698 gulong addOnSelectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 699 { 700 return Signals.connect(this, "select-all", dlg, connectFlags ^ ConnectFlags.SWAPPED); 701 } 702 703 /** 704 * Emitted when the set of selected children changes. 705 * 706 * Use [method@Gtk.FlowBox.selected_foreach] or 707 * [method@Gtk.FlowBox.get_selected_children] to obtain the 708 * selected children. 709 */ 710 gulong addOnSelectedChildrenChanged(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 711 { 712 return Signals.connect(this, "selected-children-changed", dlg, connectFlags ^ ConnectFlags.SWAPPED); 713 } 714 715 /** 716 * Emitted to toggle the selection of the child that has the focus. 717 * 718 * This is a [keybinding signal](class.SignalAction.html). 719 * 720 * The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>Space</kbd>. 721 */ 722 gulong addOnToggleCursorChild(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 723 { 724 return Signals.connect(this, "toggle-cursor-child", dlg, connectFlags ^ ConnectFlags.SWAPPED); 725 } 726 727 /** 728 * Emitted to unselect all children of the box, 729 * if the selection mode permits it. 730 * 731 * This is a [keybinding signal](class.SignalAction.html). 732 * 733 * The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>. 734 */ 735 gulong addOnUnselectAll(void delegate(FlowBox) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 736 { 737 return Signals.connect(this, "unselect-all", dlg, connectFlags ^ ConnectFlags.SWAPPED); 738 } 739 }